/*
 * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef OT_CDAF_H
#define OT_CDAF_H

#include "ot_common.h"
#include "ot_af_common.h"
#include "ot_motor.h"

typedef struct {
    ot_vi_pipe pipe;
} OT_CDAF_InitParam;

/// @brief Lens movement directions.
typedef enum {
    OT_SEARCH_DIRECTION_NEAR,              ///< Move towards MACRO position
    OT_SEARCH_DIRECTION_FAR,               ///< Move towards infinity position
    OT_SEARCH_DIRECTION_BOTH,              ///< both direction
    OT_SEARCH_DIRECTION_BUTT
} OT_CDAF_SearchDirection;

// =============================================================================
// OT_CDAF_SearchMode: Type of algorithm currently supported
// =============================================================================

typedef enum {
    OT_SEARCHM_MODE_FULL_SWEEP,
    OT_SEARCHM_MODE_PARALLEL_SEARCH,
    OT_SEARCHM_MODE_FINE_SEARCH,
    OT_SEARCHM_MODE_BUTT
} OT_CDAF_SearchMode;

typedef enum {
    OT_SEARCHM_STATUS_IDLE,
    OT_SEARCHM_STATUS_SEARCHING,
    OT_SEARCHM_STATUS_FINISHED,
    OT_SEARCHM_STATUS_ERROR,
    OT_SEARCHM_STATUS_BUTT
} OT_CDAF_SearchStatus;

typedef struct {
    td_u32 focusValue;
    td_u32 y;
} OT_AF_CDAF_FvInfoDesc;

typedef struct {
    td_u64 timestamp;
    td_u32 y;
    td_u32 focusValue;
    OT_AF_CDAF_FvInfoDesc fixed[MAX_FIXED_WINDOW_HEIGHT_NUM][MAX_FIXED_WINDOW_WIDTH_NUM];
    OT_AF_CDAF_FvInfoDesc flexible[MAX_FLEXIBLE_WINDOW_NUM];
} OT_AF_CDAF_FvInfoResult;

typedef struct {
    td_u64 timestamp;
    td_s32 stepCode;
    td_u32 focusValue;
    td_u32 y;
    td_bool flatSceneFlag; /* Indicates whether a flat scene is detected. */
    OT_CDAF_SearchStatus searchStatus;
} OT_CDAF_Results;

// @brief Types of Set input parameters for the algorithm.
typedef enum {
    OT_SET_PARAM_TYPE_FOCUS_WINDOW_PARAMS,
    OT_SET_PARAM_TYPE_FIXED_WINDOW_PARAMS,
    OT_SET_PARAM_TYPE_SEARCH_PARAMS,
    OT_SET_PARAM_TYPE_FIXED_FLEXIBLE_WINDOW_PARAMS, // OT_AF_WindowConfig windowConfig;
    OT_SET_PARAM_TYPE_BUTT
} OT_CDAF_SetParamType;

typedef struct {
    td_s32 maxCode; /* Nearest position lens can move to  */
    td_s32 minCode; /* Farest position lens can move to  */
    td_s32 minStepCode;
    td_s32 maxStepCode;
    OT_CDAF_SearchMode searchMode;
    OT_CDAF_SearchDirection searchDirection;
} OT_CDAF_SearchParams;

/// @brief Base structure of a Set parameter for CDAF
typedef struct {
    td_void *data;                     /*  Pointer to the parameter payload. */
    td_u32 sizeOfData;                 /*  Size of the payload data. */
    OT_CDAF_SetParamType setParamType; /*  Type of parameter that is passed to the algorithm. */
} OT_CDAF_SetParams;

typedef struct {
    td_s32 curCode;
} OT_CDAF_FocusParam;


typedef enum {
    OT_ERR_CDAF_OK = 0,
    OT_ERR_CDAF_NOT_INIT,
    OT_ERR_CDAF_NULL_PTR,
    OT_ERR_CDAF_INVALID_PIPE_ID,
    OT_ERR_CDAF_INVALID_SET_PARAMS,
    OT_ERR_CDAF_INVALID_SEARCH_PARAMS,
    OT_ERR_CDAF_INVALID_FOCUS_PARAM,
    OT_ERR_CDAF_SET_PARAM_FAILURE,
    OT_ERR_CDAF_WIN_FAILURE,
    OT_ERR_CDAF_HAS_INITED,
} OT_CDAF_ErrorCode;

typedef struct {
    OT_AF_AlgInfo info;
    td_s32 (*init)(td_void **handle, const OT_CDAF_InitParam *initParam);
    td_s32 (*deinit)(td_void *handle);
    td_s32 (*setParam)(td_void *handle, OT_CDAF_SetParams *setParams);
    td_s32 (*process)(td_void *handle, const OT_CDAF_FocusParam *focusParam, OT_CDAF_Results *result);  // 17X15
    td_s32 (*calculateFocusValue)(td_void *handle, OT_AF_CDAF_FvInfoResult *result);
} OT_AF_CDAFAlgIntf;

OT_AF_CDAFAlgIntf *SS_CDAF_GetCDAFAlg(td_void);

#endif
